package me.yushuai.wukong.base.service.impl;

import me.yushuai.wukong.base.api.dto.CreateZoneGroupDTO;
import me.yushuai.wukong.base.api.dto.PagingSearchZoneGroup;
import me.yushuai.wukong.base.api.dto.UpdateZoneGroupDTO;
import me.yushuai.wukong.base.api.dto.ZoneGroupDTO;
import me.yushuai.wukong.base.convertor.ZoneGroupConvertor;
import me.yushuai.wukong.base.entity.ZoneGroup;
import me.yushuai.wukong.base.repository.ZoneGroupRepository;
import me.yushuai.wukong.base.service.ZoneGroupService;
import me.yushuai.wukong.common.dto.PageDTO;
import me.yushuai.wukong.common.exceptin.BizIdNotExistException;
import me.yushuai.wukong.common.exceptin.DuplicateBizIdException;
import me.yushuai.wukong.common.exceptin.NotExistException;
import me.yushuai.wukong.common.service.impl.AbstractPageableService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

/**
 * 区域业务实现类
 *
 * @author zhoushuai@189.cn
 * @since 2022-08-31
 */
@Service
public class ZoneGroupServiceImpl extends AbstractPageableService<ZoneGroupDTO, ZoneGroup> implements ZoneGroupService {

    public static final String ZONE_GROUP_CODE_HAS_EXIST = "zoneGroup.zoneGroupCode.hasExist";

    public static final String ZONE_GROUP_ID_NOT_FOUND = "zoneGroup.zoneGroupId.notFound";

    @Autowired
    private ZoneGroupConvertor zoneGroupConvertor;

    private final ZoneGroupRepository zoneGroupRepository;

    public ZoneGroupServiceImpl(ZoneGroupRepository zoneGroupRepository) {
        super(zoneGroupRepository);
        this.zoneGroupRepository = zoneGroupRepository;
    }

    @Override
    public Long createZoneGroup(CreateZoneGroupDTO dto) throws DuplicateBizIdException {
        //1. 检查SKU是存在
        final String bizId = dto.getBizId();
        if (this.existsByBizId(bizId)) {
            throw new DuplicateBizIdException(bizId, ZoneGroup.class);
        }

        //2. 检查所属仓库是否存在 TODO

        //3. 新增区域
        final ZoneGroup zoneGroup = new ZoneGroup();
        BeanUtils.copyProperties(dto, zoneGroup);
        this.zoneGroupRepository.save(zoneGroup);
        return zoneGroup.getZoneGroupId();
    }

    @Override
    public Long updateZoneGroup(UpdateZoneGroupDTO dto) throws BizIdNotExistException {

        //1. 检查区域是否存在
        final ZoneGroup zoneGroup = this.getZoneGroupOrThrow(dto.getBizId());

        //2. 通过区域编号更新区域信息
        this.zoneGroupConvertor.mapToZoneGroup(dto, zoneGroup);
        this.zoneGroupRepository.save(zoneGroup);

        return zoneGroup.getZoneGroupId();
    }

    @Override
    public void deleteZoneGroup(Long zoneGroupId) throws NotExistException {
        //1. 检查区域是否存在
        if (this.existsById(zoneGroupId)) {
            throw new NotExistException(zoneGroupId, ZoneGroup.class);
        }

        //2. 删除区域记录
        this.zoneGroupRepository.deleteById(zoneGroupId);
    }


    @Override
    public ZoneGroupDTO findZoneGroupById(Long zoneGroupId) throws NotExistException {

        final ZoneGroup zoneGroup = getZoneGroupOrThrow(zoneGroupId);

        //3. 返回查询结果
        return this.zoneGroupConvertor.mapToZoneGroupDTO(zoneGroup);
    }


    @Override
    public ZoneGroupDTO findZoneGroupByBizId(String bizId) throws BizIdNotExistException {
        final ZoneGroup zoneGroup = getZoneGroupOrThrow(bizId);
        return this.zoneGroupConvertor.mapToZoneGroupDTO(zoneGroup);
    }


    @Override
    public PageDTO<ZoneGroupDTO> pagingSearchZoneGroup(PagingSearchZoneGroup pagingSearch) {
        //1. prepare query conditions
        final Specification<ZoneGroup> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            return criteriaBuilder.and(list.toArray(Predicate[]::new));
        };

        return super.pagingSearch(pagingSearch, spec, zoneGroupConvertor::mapToZoneGroupDTOList);
    }

    @Override
    public boolean existsById(Long zoneGroupId) {
        return this.zoneGroupRepository.existsById(zoneGroupId);
    }

    @Override
    public boolean existsByBizId(String bizId) {
        return this.zoneGroupRepository.existsByBizId(bizId);
    }

    private ZoneGroup getZoneGroupOrThrow(Long zoneGroupId) throws NotExistException {
        return this.zoneGroupRepository.findById(zoneGroupId)
                .orElseThrow(() -> new NotExistException(zoneGroupId, ZoneGroup.class));
    }

    private ZoneGroup getZoneGroupOrThrow(String bizId) throws BizIdNotExistException {
        return this.zoneGroupRepository.findByBizId(bizId)
                .orElseThrow(() -> new BizIdNotExistException(bizId, ZoneGroup.class));
    }
}




